
#include <SDL/SDL.h>

#include "screen.h"
#include "image.h"
#include "memory.h"
#include "object.h"



Image Screen::set(int wide, int high, int depth, bool fullscreen , bool doublebuffer) {   
    Uint32 bpp;
    Uint32 flags = SDL_HWSURFACE ;
	if(fullscreen)   { flags = flags | SDL_FULLSCREEN ;	}
    if(doublebuffer) { flags = flags | SDL_DOUBLEBUF; 	}
    printf("Checking mode %dx%d@%dbpp.\n", wide, high, depth);
    bpp =   SDL_VideoModeOK(640, 480, 16, flags);
    if(!bpp){
        printf("Mode not available.\n");
        return NULL;
    }
    printf("SDL Recommends %dx%d@%dbpp.\n", wide, high, bpp);
    _surface = SDL_SetVideoMode(640, 480, bpp, flags);
	if(_surface) { 
		SDL_WM_SetCaption("Eruta", "Eruta");
	}
    return _surface;
}

int Screen::wide() {
    return _surface->w;
}

int Screen::high() {
    return _surface->h;
}

void Screen::flip() {
    SDL_Flip(_surface);
}

Screen screen_blit_size(Screen self, Image surface, 
        int src_x, int src_y, int src_w, int src_h, int tar_x, int tar_y ) 
{
   image_blit_size(self._surface, tar_x, tar_y, surface, src_x, src_y, src_w, src_h);
   return self;
}


void Screen::blit(int tar_x, int tar_y, Image surface ) 
{
    image_blit(_surface, tar_x, tar_y, surface);
}

Image Screen::make_image(int wide, int high) {
    Image result;
    Uint32 flags = SDL_HWSURFACE | SDL_SRCALPHA;
    result = SDL_CreateRGBSurface(flags, wide, high, 
                                  _surface->format->BitsPerPixel,
                                  _surface->format->Rmask, 
                                  _surface->format->Gmask, 
                                  _surface->format->Bmask,
                                  _surface->format->Amask);
    return result;
}


Ropelist Font::split_multi(Fontpointer font, const Rope text, const int maxwide) {
	Ropelist  		result;
	Rope 			line;
	Rope 	 		split(" \n\t\r");
	Ropelist list 	= text.split_any(split); 
	int linehigh 	= Font::linehigh(font);
	int linewide    = 0;
	int spacewide	= charwide(font, ' ');
	bool linestart  = true;
	int wordwide    = 0;
	int lastwordwide= 0;
	int stop =	list.size();
	for (int index = 0; index < stop  ; index ++) {
		Rope word 		= list[index];
		wordwide 		= Font::stringwide(font, word.c_str());
		linewide 		= Font::stringwide(font, line.c_str());
		if(wordwide >= maxwide) { 
			// The word is too wide to ever fit on one line. Put it in the line anyway;
			if(!linestart) { 
				line.append(" ");	
			} 
			line.append(word);	
			result.push_back(line);
			line = "";								
		} else if( (wordwide + spacewide + linewide) > maxwide ) {
			// The word doesn't fit on this line. Move on to the beginning of the next line.
			result.push_back(line);
			line 		= word;				
			linestart 	= false;
		} else {
			if(!linestart) { 
				line.append(" ");
			}
			line.append(word);	
			linestart = false;
		}
	}
	/*if(line.size() > 0) */ {
		result.push_back(line);
	}
	return result;
}

Ropelist Font::split_multi_paragraph
		(Fontpointer font, const char * utf8text, const int maxwide) {
	Rope text(utf8text);	
	Ropelist result;
	Ropelist paragraphs = text.split_any("\n");
	// Split in paragraphs by newline characters.
	for (int pindex = 0; pindex < paragraphs.size(); pindex ++) {
		Ropelist lines = 
		split_multi(font, paragraphs[pindex], maxwide);
		// Split the paragraphs in lines, according to the maximum allowed width 
		// and the font properties.
		for(int lindex = 0; lindex < lines.size(); lindex ++) {
			result.push_back(lines[lindex]);
			// And append the lines to the vector.	
		}
	}
	return result;
}
	
Preptext Font::prepare_text(Fontpointer font, const char * utf8text, const int maxwide) {
	Preptext preptext;
	preptext.lines 		= split_multi_paragraph(font, utf8text, maxwide);
	preptext.linecount  = preptext.lines.size();
	preptext.linehigh 	= Font::linehigh(font);
	preptext.high 		= preptext.linehigh * preptext.linecount; 
	preptext.wide       = maxwide;
	return preptext;

}


	
Image Font::draw_prepared(Screen screen, Fontpointer font, Preptext prepared) {
	// Image result 		= screen.make_image(prepared.wide, prepared.high);	
	// 
    Image result = image_make(prepared.wide, prepared.high, true);
    // SDL_SetAlpha(result, SDL_SRCALPHA, 200); 
    // SDL_SetColorKey(result, SDL_SRCCOLORKEY, 0);
    // image_fill_all_alpha(result, 0, 0, 0, 255);	
	int drawx 			= 0;
	int drawy			= 0;
	// Draw the text line by line. 	
	for (int index = 0; index < prepared.linecount ; index ++) {
		Rope  line 		= prepared.lines[index];
		Image lineimage = draw(font, line.c_str()); 
		// If we don't get a line image, it's probably just an empty line, so we can skip it safely.
		//If se get an image, draw it! :)
		if(lineimage) { 
		    SDL_SetColorKey(lineimage, SDL_SRCCOLORKEY, 0);
			// This is al ittle trick that will make the image transparent.
			// Color index 0 is the background, but we set that to transparent 
			// To get rid of the backgound fills.
			image_blit(result, drawx, drawy, lineimage);	
			image_free(lineimage);
		// Don't forget to free the lines after blitting the line image to the result.	
		} 
		
		drawy 		   += prepared.linehigh;
	}
	return result;
}

Image Font::draw_multi
	(Screen screen, Fontpointer font, const char * utf8text, const int maxwide) {
	Preptext preptext = prepare_text(font, utf8text, maxwide);	
	return draw_prepared(screen, font, preptext); 
}
